package com.bai.localshop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.bai.localshop.context.BaseContext;
import com.bai.localshop.exception.BaseException;
import com.bai.localshop.mapper.RoleMapper;
import com.bai.localshop.mapper.AuthMapper;
import com.bai.localshop.mapper.UserRoleMapper;
import com.bai.localshop.pojo.dto.UserDTO;
import com.bai.localshop.pojo.dto.UserLoginDTO;
import com.bai.localshop.pojo.dto.UserRegisterDTO;
import com.bai.localshop.pojo.dto.UserUpdateDTO;
import com.bai.localshop.pojo.entity.Role;
import com.bai.localshop.pojo.entity.User;
import com.bai.localshop.pojo.entity.UserRole;
import com.bai.localshop.pojo.vo.UserLoginVO;
import com.bai.localshop.properties.JwtProperties;
import com.bai.localshop.service.AuthService;
import com.bai.localshop.utils.JwtUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.bai.localshop.constant.RedisCacheConstant.LOCK_USER_REGISTER_KEY;

@Service
@RequiredArgsConstructor
public class AuthServiceImpl extends ServiceImpl<AuthMapper, User> implements AuthService {
    //    private final RBloomFilter<String> userRegisterCachePenetrationBloomFilter;
    private final RedissonClient redissonClient;
    private final JwtProperties jwtProperties;
    private final StringRedisTemplate stringRedisTemplate;
    private final UserRoleMapper userRoleMapper;
    private final RoleMapper roleMapper;

    /**
     * 根据用户ID查询用户信息（包含角色名称）
     */
    @Override
    public UserDTO getUserById(Long id) {
        // 1. 查询用户基本信息
        User user = baseMapper.selectById(id);
        if (user == null) {
            throw new BaseException("用户不存在");
        }

        // 2. 创建DTO并复制基本属性
        UserDTO userDTO = new UserDTO();
        BeanUtil.copyProperties(user, userDTO);

        // 3. 获取角色名称（管理员优先）
        String roleName = getUserRoleName(user.getId());
        userDTO.setRoleName(roleName);

        return userDTO;
    }

    /**
     * 查询用户名是否存在
     *
     * @param username
     * @return
     */
    @Override
    public Boolean hasUsername(String username) {
        LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery(User.class)
                .eq(User::getUsername, username);
        User user = baseMapper.selectOne(queryWrapper);
        if (user == null) {
            //用户名不存在，返回false
            return false;
        }
        return true;
    }

    /**
     * 用户注册
     *
     * @param requestParam
     */
    @Override
    public void register(UserRegisterDTO requestParam) {
        if (hasUsername(requestParam.getUsername())) {
            //用户名存在
            throw new BaseException("用户名已存在");
        }
        RLock lock = redissonClient.getLock(LOCK_USER_REGISTER_KEY + requestParam.getUsername());
        try {
            if (lock.tryLock()) {
                User user = BeanUtil.toBean(requestParam, User.class);
                // 使用BCrypt加密
                String encodedPassword = BCrypt.hashpw(requestParam.getPassword(), BCrypt.gensalt());
                user.setPassword(encodedPassword);
                int insert = baseMapper.insert(user);
                if (insert < 1) {
                    //新增失败
                    throw new BaseException("注册失败");
                }
                // 分配默认角色（如user）
                UserRole userRole = new UserRole();
                userRole.setUserId(user.getId());
                userRole.setRoleId(2L); // 假设2是普通用户角色ID
                userRoleMapper.insert(userRole);

                //TODO 布隆过滤器
                return;
            }
            throw new BaseException("用户名已存在");
        } finally {
            lock.unlock();
        }
    }

    /**
     * 修改用户
     */
    @Override
    public void update(UserUpdateDTO requestParam) {
        LambdaUpdateWrapper<User> updateWrapper = Wrappers.lambdaUpdate(User.class)
                .eq(User::getId, BaseContext.getCurrentId());
        baseMapper.update(BeanUtil.toBean(requestParam, User.class), updateWrapper);
    }

    /**
     * 判断是否为管理员
     *
     * @param userId
     * @return
     */
    @Override
    public boolean isAdmin(Long userId) {
        LambdaQueryWrapper<UserRole> queryWrapper = Wrappers.lambdaQuery(UserRole.class)
                .eq(UserRole::getUserId, userId);
        UserRole userRole = userRoleMapper.selectOne(queryWrapper);

        if (userRole != null) {
            // 这里假设角色ID为1的是管理员，根据你的实际情况调整
            return userRole.getRoleId() == 1L;
        }
        return false;
    }

    /**
     * 用户登录
     */
    @Override
    public UserLoginVO login(UserLoginDTO requestParam) {
        LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery(User.class)
                .eq(User::getUsername, requestParam.getUsername());
        User user = baseMapper.selectOne(queryWrapper);
        if (user == null) {
            throw new BaseException("用户不存在");
        }
        //查询用户状态
        if (user.getStatus()==0){
            throw new BaseException("当前用户已被禁用，请联系管理员处理");
        }
        // 使用 BCrypt 验证密码
        boolean passwordMatches = BCrypt.checkpw(
                requestParam.getPassword(),
                user.getPassword()
        );
        if (!passwordMatches) {
            throw new BaseException("用户名或密码错误");
        }

        // 统一使用用户JWT配置
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", user.getId());

        String token = JwtUtil.createJWT(
                jwtProperties.getUserSecretKey(), // 改为用户密钥
                jwtProperties.getUserTtl(),       // 改为用户过期时间
                claims);

        // 存入缓存
        stringRedisTemplate.opsForValue().set(
                "login:" + user.getId(),
                token,
                jwtProperties.getUserTtl(),
                TimeUnit.MILLISECONDS
        );

        // 获取用户角色名称
        String roleName = getUserRoleName(user.getId());

        return new UserLoginVO(
                token,
                user.getId(),
                user.getUsername(),
                user.getPhone(),
                user.getEmail(),
                roleName
        );
    }

    /**
     * 检查用户是否登录
     */
    @Override
    public Boolean checkLogin() {
        return stringRedisTemplate.opsForValue().get("login:" + BaseContext.getCurrentId()) != null;
    }

    /**
     * 退出登录
     */
    @Override
    public void logout() {
        if (checkLogin()) {
            stringRedisTemplate.delete("login:" + BaseContext.getCurrentId());
        }
    }

    /**
     * 获取用户角色名称
     */
    private String getUserRoleName(Long userId) {
        try {
            // 查询用户的所有角色
            LambdaQueryWrapper<UserRole> userRoleQuery = Wrappers.lambdaQuery(UserRole.class)
                    .eq(UserRole::getUserId, userId);
            List<UserRole> userRoles = userRoleMapper.selectList(userRoleQuery);
            if (userRoles.isEmpty()) {
                return "普通用户";
            }
            // 检查是否有管理员角色
            for (UserRole userRole : userRoles) {
                Role role = roleMapper.selectById(userRole.getRoleId());
                if (role != null && role.getStatus() == 1 && "admin".equals(role.getRoleCode())) {
                    return "管理员";
                }
            }
            // 默认返回用户
            return "普通用户";

        } catch (Exception e) {
            return "普通用户";
        }
    }
}